From 3d233743ec4a2a7724089ebefe8337bc6bc6cfe2 Mon Sep 17 00:00:00 2001 From: Marek Kasik Date: Wed, 30 Aug 2017 17:56:00 +0200 Subject: [PATCH] printing: Don't show duplicate printers Check UUID for printers obtained via DNSSD whether they are already installed on local CUPS server. Don't show such printers. Not all printers published via DNSSD have UUID entry though. https://bugzilla.gnome.org/show_bug.cgi?id=786794 --- .../printbackends/cups/gtkprintbackendcups.c | 64 ++++++++++++++++++- modules/printbackends/cups/gtkprintercups.c | 2 + modules/printbackends/cups/gtkprintercups.h | 1 + 3 files changed, 66 insertions(+), 1 deletion(-) diff --git a/modules/printbackends/cups/gtkprintbackendcups.c b/modules/printbackends/cups/gtkprintbackendcups.c index 9d23bc1011..abc5f841c6 100644 --- a/modules/printbackends/cups/gtkprintbackendcups.c +++ b/modules/printbackends/cups/gtkprintbackendcups.c @@ -1899,7 +1899,8 @@ static const char * const printer_attrs[] = "ipp-versions-supported", "multiple-document-handling-supported", "copies-supported", - "number-up-supported" + "number-up-supported", + "device-uri" }; /* Attributes we're interested in for printers without PPD */ @@ -1996,11 +1997,13 @@ typedef struct int number_of_covers; gchar *output_bin_default; GList *output_bin_supported; + gchar *original_device_uri; } PrinterSetupInfo; static void printer_setup_info_free (PrinterSetupInfo *info) { + g_free (info->original_device_uri); g_free (info->state_msg); g_strfreev (info->covers); g_slice_free (PrinterSetupInfo, info); @@ -2376,6 +2379,10 @@ cups_printer_handle_attribute (GtkPrintBackendCups *cups_backend, info->output_bin_supported = g_list_reverse (info->output_bin_supported); } + else if (g_strcmp0 (ippGetName (attr), "device-uri") == 0) + { + info->original_device_uri = g_strdup (ippGetString (attr, 0, NULL)); + } else { GTK_NOTE (PRINTING, @@ -2464,6 +2471,7 @@ cups_create_printer (GtkPrintBackendCups *cups_backend, cups_printer->default_cover_before = g_strdup (info->default_cover_before); cups_printer->default_cover_after = g_strdup (info->default_cover_after); + cups_printer->original_device_uri = g_strdup (info->original_device_uri); if (info->default_number_up > 0) cups_printer->default_number_up = info->default_number_up; @@ -2830,9 +2838,54 @@ typedef struct guint printer_state; gchar *type; gchar *domain; + gchar *UUID; GtkPrintBackendCups *backend; } AvahiConnectionTestData; +static GtkPrinter * +find_printer_by_uuid (GtkPrintBackendCups *backend, + const gchar *UUID) +{ + GtkPrinterCups *printer; + GtkPrinter *result = NULL; + GList *printers; + GList *iter; + gchar *printer_uuid; + + printers = gtk_print_backend_get_printer_list (GTK_PRINT_BACKEND (backend)); + for (iter = printers; iter != NULL; iter = iter->next) + { + printer = GTK_PRINTER_CUPS (iter->data); + if (printer->original_device_uri != NULL) + { + printer_uuid = g_strrstr (printer->original_device_uri, "uuid="); + if (printer_uuid != NULL && strlen (printer_uuid) >= 41) + { + printer_uuid += 5; + printer_uuid = g_strndup (printer_uuid, 36); + +#if GLIB_CHECK_VERSION(2, 52, 0) + if (g_uuid_string_is_valid (printer_uuid)) +#endif + { + if (g_strcmp0 (printer_uuid, UUID) == 0) + { + result = GTK_PRINTER (printer); + g_free (printer_uuid); + break; + } + } + + g_free (printer_uuid); + } + } + } + + g_list_free (printers); + + return result; +} + /* * Create new GtkPrinter from informations included in TXT records. */ @@ -2878,6 +2931,10 @@ create_cups_printer_from_avahi_data (AvahiConnectionTestData *data) set_info_state_message (info); printer = gtk_print_backend_find_printer (GTK_PRINT_BACKEND (data->backend), data->printer_name); + + if (printer == NULL && data->UUID != NULL) + printer = find_printer_by_uuid (data->backend, data->UUID); + if (printer == NULL) { printer = cups_create_printer (data->backend, info); @@ -3080,6 +3137,11 @@ avahi_service_resolver_cb (GObject *source_object, if (data->printer_state != 0 || endptr != value) data->got_printer_state = TRUE; } + else if (g_strcmp0 (key, "UUID") == 0) + { + if (*value != '\0') + data->UUID = g_strdup (value); + } g_clear_pointer (&key, g_free); g_clear_pointer (&value, g_free); diff --git a/modules/printbackends/cups/gtkprintercups.c b/modules/printbackends/cups/gtkprintercups.c index 4a94cbd09d..068aba74c5 100644 --- a/modules/printbackends/cups/gtkprintercups.c +++ b/modules/printbackends/cups/gtkprintercups.c @@ -100,6 +100,7 @@ static void gtk_printer_cups_init (GtkPrinterCups *printer) { printer->device_uri = NULL; + printer->original_device_uri = NULL; printer->printer_uri = NULL; printer->state = 0; printer->hostname = NULL; @@ -151,6 +152,7 @@ gtk_printer_cups_finalize (GObject *object) printer = GTK_PRINTER_CUPS (object); g_free (printer->device_uri); + g_free (printer->original_device_uri); g_free (printer->printer_uri); g_free (printer->hostname); g_free (printer->ppd_name); diff --git a/modules/printbackends/cups/gtkprintercups.h b/modules/printbackends/cups/gtkprintercups.h index 837035a9c6..f26bbab677 100644 --- a/modules/printbackends/cups/gtkprintercups.h +++ b/modules/printbackends/cups/gtkprintercups.h @@ -48,6 +48,7 @@ struct _GtkPrinterCups GtkPrinter parent_instance; gchar *device_uri; + gchar *original_device_uri; gchar *printer_uri; gchar *hostname; gint port; -- 2.30.2